package org.example.java_gobang.game;

import com.fasterxml.jackson.databind.ObjectMapper;

import org.example.java_gobang.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;

//匹配器
@Component
public class Matcher {

    // 三个匹配队列
    private Queue<User> normalQueue = new LinkedList<>();
    private Queue<User> highQueue = new LinkedList<>();
    private Queue<User> veryHighQueue = new LinkedList<>();

    // 玩家在线状态
    @Autowired
    private OnlineUserManager onlineUserManager;
    private ObjectMapper objectMapper = new ObjectMapper();
    @Autowired
    private RoomManager roomManager;



    //把玩家放入 匹配队列   匹配队列
    public void add(User user) throws InterruptedException {

        if (user.getScore() < 2000) {
            synchronized (normalQueue) {
                normalQueue.offer(user);
                normalQueue.notify();
            }

            System.out.println("玩家 " + user.getUsername() + " 进⼊ normalQueue!");
        } else if (user.getScore() < 3000) {
            synchronized (highQueue) {
                highQueue.offer(user);
                highQueue.notify();
            }

            System.out.println("玩家 " + user.getUsername() + " 进⼊ highQueue!");
        } else {
            synchronized (veryHighQueue) {
                veryHighQueue.offer(user);
                veryHighQueue.notify();
            }

            System.out.println("玩家 " + user.getUsername() + " 进⼊ veryHighQueue!");
        }
    }

    public void remove(User user) {
        if (user.getScore() < 2000) {
            synchronized (normalQueue) {
                removeFromQueue(normalQueue, user);
            }

            System.out.println("把玩家 " + user.getUsername() + " 移出 normalQueue!");
        } else if (user.getScore() < 3000) {
            synchronized (highQueue) {
                removeFromQueue(highQueue, user);
            }

            System.out.println("把玩家 " + user.getUsername() + " 移出 highQueue!");
        } else {
            synchronized (veryHighQueue) {
                removeFromQueue(veryHighQueue, user);
            }

            System.out.println("把玩家 " + user.getUsername() + " 移出 veryHighQueue!");
        }
    }

    private void removeFromQueue(Queue<User> queue, User user) {
        queue.remove(user);
    }

    private Matcher() {
        // 搞三个线程, 各⾃匹配各⾃的~
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    handlerMatch(normalQueue);
                }
            }
        }.start();
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    handlerMatch(highQueue);
                }
            }
        }.start();
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    handlerMatch(veryHighQueue);
                }
            }
        }.start();

    }
    //匹配时的处理
    private void handlerMatch(Queue<User> matchQueue) {
        synchronized (matchQueue) {
            try {
                //1.检测队列里面玩家个数
                //队列的初始情况可能为空,要是添加一个不够两个被唤醒一下也是要wait,所以要循环检查,使用while不是if
                while (matchQueue.size() < 2) {
                    matchQueue.wait();

                }

                //2.从队列里面取出两个玩家
                User player1 = matchQueue.poll();
                User player2 = matchQueue.poll();
                System.out.println("匹配到两个玩家: " + player1.getUsername() + ",  " + player2.getUsername());

                //3.获取到websocket的会话
                WebSocketSession session1 = onlineUserManager.getSessionFromGameHall(player1.getUserId());
                WebSocketSession session2 = onlineUserManager.getSessionFromGameHall(player2.getUserId());
                if (session1 == null) {
                    //如果玩家1不在线,就把玩家2放回匹配队列
                    matchQueue.offer(player2);
                    return;
                }
                if (session2 == null) {
                    //如果玩家2不在线,就把玩家1放回匹配队列
                    matchQueue.offer(player1);
                    return;
                }
                //排到两个玩家是同一个用户的情况(理论上多开不存在,前面已经处理)
                if (session1 == session2) {
                    matchQueue.offer(player1);
                    return;
                }

                //4.把两个玩家放入一个房间里面
                Room room = new Room();
                roomManager.add(room, player1.getUserId(), player2.getUserId());


                //5.给两个玩家都要反馈信息,你已经匹配成功
                MatchResponse response1 = new MatchResponse();
                response1.setOk(true);
                response1.setMessage("matchSuccess");
                String json1 = objectMapper.writeValueAsString(response1);
                session1.sendMessage(new TextMessage(json1));


                MatchResponse response2 = new MatchResponse();
                response2.setOk(true);
                response2.setMessage("matchSuccess");
                String json2 = objectMapper.writeValueAsString(response2);
                session2.sendMessage(new TextMessage(json2));
            } catch (IOException | InterruptedException e){
                e.printStackTrace();
            }

        }
    }

}
